package com.yuchao.base.xyc003;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

/**
 * 为什么使用LocalDate ,不用Date?
 * SimpleDateFormat对时间进行格式化，但 SimpleDateFormat是线程不安全的
 *
 * 多线程并发如何保证线程安全 - 避免线程之间共享一个 SimpleDateFormat对象，每
 * 个线程使用时都创建一次 SimpleDateFormat对象 => 创建和销毁对象的开销大 -
 * 对使用 format和 parse方法的地方进行加锁 => 线程阻塞性能差 - 使用 ThreadLocal保证
 * 每个线程最多只创建一次 SimpleDateFormat对象 => 较好的方法
 * @description:
 * @author: xingyuchao
 * @date: 2019-11-06
 */
public class Main {

    public static void main(String[] args) {

        //-------------LocalDate  只会获取年月日-------------------------
        //获取当前年月日
        LocalDate localDate = LocalDate.now();
        System.out.println(localDate);

        //构造指定的年月日
        LocalDate localDate1 = LocalDate.of(2019, 9, 10);
        System.out.println(localDate1);

        //获取年、月、日、星期几
        getLocalDateInfo(localDate);



        //-------------LocalTime  只会获取几点几分几秒-------------------------
        //创建 LocalTime
        LocalTime localTime = LocalTime.now();
        System.out.println(localTime);

        //构造指定的时间
        LocalTime localTime1 = LocalTime.of(13, 51, 10);
        System.out.println(localTime1);


        getLocalTimeInfo(localTime);

        //-------------LocalDateTime  获取年月日时分秒，等于LocalDate+LocalTime-------------------------

        //创建 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);

        //构造指定的LocalDateTime
        LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
        System.out.println(localDateTime1);

        LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
        System.out.println(localDateTime2);

        LocalDateTime localDateTime3 = localDate.atTime(localTime);
        System.out.println(localDateTime3);

        LocalDateTime localDateTime4 = localTime.atDate(localDate);
        System.out.println(localDateTime4);

        //获取 LocalDate
        LocalDate localDate2 = localDateTime.toLocalDate();
        System.out.println(localDate2);

        //获取 LocalTime
        LocalTime localTime2 = localDateTime.toLocalTime();
        System.out.println(localTime2);




        //-------------Instant   获取秒数-------------------------
        //创建 Instant对象
        Instant instant = Instant.now();
        System.out.println(instant);
        //获取秒数
        long currentSecond = instant.getEpochSecond();
        System.out.println(currentSecond);
        //获取毫秒数
        //如果只是为了获取秒数或者毫秒数，使用 System.currentTimeMillis()来得更为方便
        long currentMilli = instant.toEpochMilli();
        System.out.println(currentMilli);



        //修改LocalDate、LocalTime、LocalDateTime、Instant
        //LocalDate、 LocalTime、 LocalDateTime、 Instant为不可变对象，修改这些对象对象会返回一个副本
        //增加一年
        localDateTime = localDateTime.plusYears(1);
        System.out.println(localDateTime);
        localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
        System.out.println(localDateTime);
        //减少一个月
        localDateTime = localDateTime.minusMonths(1);
        System.out.println(localDateTime);
        localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
        System.out.println(localDateTime);


        //通过 with修改某些值  还可以修改月、日
        //修改年为2019
        localDateTime = localDateTime.withYear(2020);

        //修改为2022
        localDateTime = localDateTime.with(ChronoField.YEAR, 2022);


        //格式化时间  和 SimpleDateFormat相比， DateTimeFormatter是线程安全的
        String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(s1);

        String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(s2);

        //自定义格式化

        DateTimeFormatter dateTimeFormatter =   DateTimeFormatter.ofPattern("dd/MM/yyyy");

        String s3 = localDate.format(dateTimeFormatter);
        System.out.println(s3);

        //DateTimeFormatter默认提供了多种格式化方式，如果默认提供的不能满足要求，可以通过 DateTimeFormatter的 ofPattern方法创建自定义格式化方式
        localDate = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println(localDate);
        localDate = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
        System.out.println(localDate);


//        SpringBoot中应用LocalDateTime
//        ◾将LocalDateTime字段以时间戳的方式返回给前端 添加日期转化类
//        public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
//            @Override
//            public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
//                gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
//            }
//        }


//        并在 LocalDateTime字段上添加 @JsonSerialize(using=LocalDateTimeConverter.class)注解，如下：
//        @JsonSerialize(using = LocalDateTimeConverter.class)
//        protected LocalDateTime gmtModified;


//        ◾将LocalDateTime字段以指定格式化日期的方式返回给前端 在 LocalDateTime字段上添加 @JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-dd HH:mm:ss")注解即可，如下：
//        @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
//        protected LocalDateTime gmtModified;




//        ◾对前端传入的日期进行格式化 在 LocalDateTime字段上添加 @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")注解即可，如下：
//        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//        protected LocalDateTime gmtModified;

    }

    /**
     * 获取时分秒
     * @param localTime
     */
    private static void getLocalTimeInfo(LocalTime localTime) {
        //获取小时
        int hour = localTime.getHour();
        System.out.println(hour);

        int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
        System.out.println(hour1);

        //获取分
        int minute = localTime.getMinute();
        System.out.println(minute);

        int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
        System.out.println(minute1);

        //获取秒
        int second = localTime.getSecond();
        System.out.println(second);

        int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
        System.out.println(second1);
    }

    /**
     * 获取年、月、日、星期几
     * @param localDate
     */
    private static void getLocalDateInfo(LocalDate localDate) {

        int year = localDate.getYear();
        System.out.println(year);

        int year1 = localDate.get(ChronoField.YEAR);
        System.out.println(year1);


        Month month = localDate.getMonth();
        System.out.println(month);

        int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
        System.out.println(month1);


        int day = localDate.getDayOfMonth();
        System.out.println(day);

        int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
        System.out.println(day1);

        DayOfWeek dayOfWeek = localDate.getDayOfWeek();
        System.out.println(dayOfWeek);

        int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
        System.out.println(dayOfWeek1);
    }
}
